using System;
using System.Diagnostics;

namespace InfiniTec.Diagnostics
{
	public class TraceOperation: IDisposable
	{
		private readonly Trace _Trace;
		private readonly int _Id;
		private readonly string _Name;
		private readonly object[] _Args;
		private readonly Guid _OldActivityId;
		private readonly Stopwatch _Watch;


		public TimeSpan ElapsedTime
		{
			get { return _Watch.Elapsed; } }

		internal TraceOperation(Trace trace, int id, string name, params object[] args)
		{
			if (trace == null) throw new ArgumentNullException("trace");
			if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");

			_OldActivityId  = Trace.ActivityId;
			_Watch = Stopwatch.StartNew();
			_Trace = trace;
			_Id = id;
			_Name = name;
			_Args = args;

			var activityId = Guid.NewGuid();

			if (args != null)
			{
				_Trace.Transfer(id, activityId, name, args);
				Trace.ActivityId = activityId;
				_Trace.Start(id, name, args);	
			}
			else
			{
				_Trace.Transfer(id, activityId, name);
				Trace.ActivityId = activityId;
				_Trace.Start(id, name);	
			}
		}

		public void Stop()
		{
			if (_Args == null)
			{
				_Trace.Stop(_Id, _Name);
			}
			else
			{
				_Trace.Stop(_Id, _Name, _Args);
			}
			Trace.ActivityId = _OldActivityId;
		}

		void IDisposable.Dispose()
		{
			Stop();
		}
	}
}